home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / UI / Disptch.cpp < prev    next >
Encoding:
Text File  |  1997-02-13  |  29.9 KB  |  1,097 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        Disptch.cpp
  3.  
  4.     Contains:    Implementation of class ODDispatcher
  5.  
  6.     Owned by:    Richard Rodseth
  7.  
  8.     Copyright:    © 1994 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <5>     9/24/96    eeh        1315228: Verify part wrapper passed
  13.          <4>     6/14/96    CSL        1257735: Can't register for idle time
  14.                                     during idle time
  15.          <3>     6/12/96    eeh        1316602: set modifiers field for
  16.                                     manufactured events (e.g. mouseMoved)
  17.          <2>     5/01/96    NP        1300091,1282521: Replace badly written bug
  18.                                     workaround, IntlTSMEvent, with TSMEvent.
  19.         <50>    10/17/95    jpa        1292659: Ignore exceptions sending null
  20.                                     events to parts
  21.         <49>    10/10/95    DM        1277216: GM:API: Dont return ODPoint from
  22.                                     GetWindowPoint()
  23.         <48>     10/3/95    TJ        Changes done by RefBall Team
  24.         <47>      9/6/95    RR        #1282075 ADded ODVolatile
  25.         <46>     8/29/95    RR        # 1276401 Respect Mouse Focus
  26.         <45>     8/26/95    TÇ        1274606 FB2: Patching Remarks
  27.         <44>     8/23/95    NP        1264142: Don't Release null object.
  28.         <43>     8/15/95    RR        #1222870 Moved NULL handling to end of
  29.                                     method to allow patching/monitors
  30.         <42>      8/3/95    RR        #1257260: Collapse B classes. Remove
  31.                                     somInit methods. Don't call IsInitialized
  32.                                     or SubclassResponsibility
  33.         <41>     6/29/95    NP        1263893: Fix TSM support.
  34.         <40>     6/25/95    TÇ        1242642 BB: Turn on ODDebug warning if
  35.                                     refcount is wrong in
  36.                                     ODRefCntObjectsomUninit.
  37.         <39>     6/23/95    CC        1256943: MouseRegionIsInvalid: Replaced
  38.                                     StillDown with Button.
  39.         <38>     6/22/95    NP        1260250: Set up correctly for call to
  40.                                     CallEventHandler.
  41.         <37>     6/20/95    JP        1251250: ChangedReleaseExtension into
  42.                                     Release
  43.         <36>     6/15/95    RR        #1254828/1255536 Added Redispatch
  44.         <35>      6/8/95    RR        #1257260 Collapse base classes. #1214898
  45.                                     StdTypes.r -> ODTypes.r
  46.         <34>     5/31/95    RR        #1251403 Release after AcquirePart
  47.         <33>     5/26/95    RR        #1251403: Multithreading naming support
  48.         <32>     5/25/95    jpa        Fixed usage of ODDebug. [1253321]
  49.         <31>     5/21/95    NP        1251212: Wrap procs with UPPs.
  50.         <30>     5/17/95    RR        #1250135/1250137/1250143 Getters increment
  51.                                     refcount
  52.         <29>     5/10/95    RR        #1239139 MouseEnter etc.  over active
  53.                                                                         border go to container. Don't send
  54.                                     until mouse up.
  55.         <28>     5/10/95    RR         #1239139 MouseEnter etc.  over active
  56.                                     border go to container. Don't send until mouse up.
  57.         <27>     4/27/95    eeh        1230798: call part::ReleaseExtension
  58.         <26>      4/7/95    RR        #1216618 Added SOM_TRY etc.
  59.         <25>      4/4/95    RR        # 1211085 Removed fThreadsAvailable,
  60.                                     #1220104 Use ODObjectsAreEqual, #1228161
  61.                                     RegisterIdle does not update frequency if
  62.                                     called twice
  63.         <24>     3/20/95    jpa        Cooperative thread support [1167943]. Moved
  64.                                     bg click handler installation to private
  65.                                     impl file [1220704].
  66.         <23>     3/10/95    RR        # 1187137 Set Cursor to arrow in
  67.                                     InvalidateFacetUnderMouse
  68.         <22>     2/24/95    jpa        Install BG-mouse-down handler [1220704].
  69.                                     Use ODNewRgn. [1220810]
  70.         <21>     2/20/95    TÇ        #1221861 BB: Incomplete AOCE support needs
  71.                                     to be removed from OpenDoc
  72.         <20>     1/31/95    RR        # 1206909 Pass ev to
  73.                                     RemoveUnregisteredIdlers
  74.         <19>     1/25/95    jpa        Include StdExts.xh [1206907]
  75.         <18>     1/13/95    RR        Replace calls to MouseEnter etc with calls
  76.                                     to HandleEvent
  77.         <17>     1/12/95    jpa        Don't use obsolete Toolbox names [1211211].
  78.                                     Change qd --> ODQDGlobals [1210936]
  79.         <16>      1/9/95    NP        1194880: SemtIntf name changes.
  80.         <15>    11/28/94    RR        Prepare for thread support
  81.         <14>     9/30/94    RR        #1167950 Allow unregistering while idling.
  82.                                     Call RemoveUnregisteredIdlers in
  83.                                     HandleNULLEvent
  84.         <13>     9/29/94    RA        1189812: Mods for 68K build.
  85.         <12>     9/20/94    NP        1187682: Initial TSM support.
  86.         <11>     9/20/94    RR        #1154046 Moved ref counting into IdleList
  87.                                     methods so that an unregistered part is not
  88.                                     released. #1156594 Call
  89.                                     WindowState->HandleAOCEMailerEvent instead
  90.                                     of calling SMPMailerEvent directly.
  91.         <10>      9/2/94    eeh        #?: added SMPMailerEvent call to enable use
  92.                                     of mailer until Richard and I agree on a
  93.                                     cleaner fix to a bug in his hamper.
  94.          <9>     8/31/94    TÇ        #1183129, #1183116, #1183119, #1183111:
  95.                                     Lots of ErrorCode cleanup.
  96.          <8>     8/15/94    JBS        1181156: UI API Cleanup
  97.          <7>     8/10/94    JBS        1179919: coordinate system bias changes
  98.          <6>      8/4/94    eeh        bug 1177981: add
  99.                                     ODDispatcherGetDispatchModule
  100.          <5>     7/27/94    eeh        Changes necessitated by WinStat.idl changes
  101.          <4>     7/26/94    eeh        ODQDPoint->Point
  102.          <3>     6/30/94    CG        Moved InitStandardDispatchModule to
  103.                                     InitDispatch from InitSession.
  104.          <2>     9/27/94    RR        Call InitBaseDispatcher
  105.          <1>     9/26/94    RR        first checked in
  106.  
  107.     To Do:
  108.         * Get Gestalt bit for gestaltHasBGMouseDown.
  109.         * Call SetBgndMouseHandler via PrivateInterfaceLib if it's exported therefrom.
  110.         * Check whether bg mousedown handler calls are exported from PrivateInterfaceLib
  111.             and use those if they are (for Copland compatibility)
  112.         
  113.     In Progress:
  114.         
  115. */
  116.  
  117.  
  118. /*
  119.  *  This file was generated by the SOM Compiler.
  120.  *  Generated using: 
  121.  *      SOM Emitter emitxtm.dll: somc/smmain.c
  122.  */
  123.  
  124. #define ODDispatcher_Class_Source
  125. #define VARIABLE_MACROS
  126. #include <Disptch.xih>
  127.  
  128. #ifndef SOM_ODDispatchModule_xh
  129. #include "DispMod.xh"
  130. #endif
  131.  
  132. #ifndef SOM_ODWindowState_xh
  133. #include "WinStat.xh"
  134. #endif
  135.  
  136. #ifndef SOM_ODWindow_xh
  137. #include "Window.xh"
  138. #endif
  139.  
  140. #ifndef SOM_ODSession_xh
  141. #include "ODSessn.xh"
  142. #endif
  143.  
  144. #ifndef _TEMPOBJ_
  145. #include <TempObj.h>
  146. #endif
  147.  
  148. #ifndef _IDLELIST_
  149. #include "IdleList.h"
  150. #endif
  151.  
  152. #ifndef _ORDCOLL_
  153. #include "OrdColl.h"
  154. #endif
  155.  
  156. #ifndef _DISPTABL_
  157. #include "DispTabl.h"
  158. #endif
  159.  
  160. #ifndef SOM_ODFacet_xh
  161. #include "Facet.xh"
  162. #endif
  163.  
  164. #ifndef SOM_ODFrame_xh
  165. #include "Frame.xh"
  166. #endif
  167.  
  168. #ifndef SOM_ODPart_xh
  169. #include "Part.xh"
  170. #endif
  171.  
  172. #ifndef _EXCEPT_
  173. #include "Except.h"
  174. #endif
  175.  
  176. #ifndef SOM_ODStandardDispatchModule_xh
  177. #include <StdDisp.xh>
  178. #endif
  179.  
  180. #ifndef _ODDEBUG_
  181. #include "ODDebug.h"
  182. #endif
  183.  
  184. #ifndef SOM_ODArbitrator_xh
  185. #include <Arbitrat.xh>
  186. #endif
  187.  
  188. #ifndef SOM_ODSemanticInterface_xh
  189. #include <SemtIntB.xh>
  190. #endif
  191.  
  192. #ifndef SOM_ODAppleEvent_xh
  193. #include <ODAplEvt.xh>
  194. #endif
  195.  
  196. #ifndef _BARRAY_
  197. #include "BArray.h"
  198. #endif
  199.  
  200. #ifndef _ODDESUTL_
  201. #include "ODDesUtl.h"
  202. #endif
  203.  
  204. #ifndef SOM_Module_OpenDoc_Foci_defined
  205. #include <Foci.xh>
  206. #endif
  207.  
  208. #ifndef SOM_Module_OpenDoc_StandardExtensions_defined
  209. #include <StdExts.xh>
  210. #endif
  211.  
  212. #ifndef _DSPUTILM_
  213. #include "DspUtilM.h"
  214. #endif
  215.  
  216. #ifndef _BGCLICKM_
  217. #include "BGClickM.h"
  218. #endif
  219.  
  220. #ifndef _ODTHREDM_
  221. #include "ODThredM.h"
  222. #endif
  223.  
  224. #ifndef __TEXTSERVICES_
  225. #include "TextServices.h"
  226. #endif
  227.  
  228. #ifndef __GESTALTEQU__
  229. #include <GestaltEqu.h>
  230. #endif
  231.  
  232. #define ODLogEvents 0
  233.  
  234. //------------------------------------------------------------------------------
  235. //    ODDispatcher
  236. //------------------------------------------------------------------------------
  237.  
  238. #pragma segment ODDispatcher
  239.  
  240. #include "DisptchB.cpp"    // Platform-independent methods, if any
  241.  
  242. SOM_Scope void  SOMLINK ODDispatcherRegisterIdle(ODDispatcher *somSelf, Environment *ev,
  243.         ODPart* part,
  244.         ODFrame* frame,
  245.         ODIdleFrequency frequency)
  246. {
  247.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  248.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherRegisterIdle");
  249.  
  250.     WASSERT_IS_PART_WRAPPER( ev, part );
  251.  
  252.     SOM_TRY
  253.     
  254.         if (part)
  255.             _fIdleList->AddIdle(ev, part, frame, frequency);
  256.  
  257.     SOM_CATCH_ALL
  258.     SOM_ENDTRY
  259. }
  260.  
  261. SOM_Scope void  SOMLINK ODDispatcherUnregisterIdle(ODDispatcher *somSelf, Environment *ev,
  262.         ODPart* part,
  263.         ODFrame* frame)
  264. {
  265.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  266.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherUnregisterIdle");
  267.  
  268.     WASSERT_IS_PART_WRAPPER( ev, part );
  269.  
  270.     SOM_TRY
  271.  
  272.         if (part)
  273.             _fIdleList->RemoveIdle(ev, part, frame);
  274.  
  275.     SOM_CATCH_ALL
  276.     SOM_ENDTRY
  277. }
  278.  
  279. SOM_Scope void  SOMLINK ODDispatcherSetIdleFrequency(ODDispatcher *somSelf, Environment *ev,
  280.         ODPart* part,
  281.         ODFrame* frame,
  282.         ODIdleFrequency frequency)
  283. {
  284.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  285.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherSetIdleFrequency");
  286.  
  287.     WASSERT_IS_PART_WRAPPER( ev, part );
  288.  
  289.     SOM_TRY
  290.  
  291.         if (part)
  292.             _fIdleList->SetIdleFrequency(ev, part, frame, frequency);
  293.  
  294.     SOM_CATCH_ALL
  295.     SOM_ENDTRY
  296. }
  297.  
  298. SOM_Scope void  SOMLINK ODDispatcherYield(ODDispatcher *somSelf, Environment *ev,
  299.         ODFrame* frame)
  300. {
  301.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  302.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherYield");
  303.  
  304.     SOM_TRY
  305.  
  306.     /*
  307.         Will Call WaitNextEvent(), masking out all but null and update events.
  308.         Idle events are sent to all but the part that yielded
  309.     */
  310.         const    ODSLong        kODSleepTicks             =     20L;//    Number sleep ticks
  311.     
  312.         EventRecord        eventRec;    
  313.         WaitNextEvent ( updateMask, &eventRec, somSelf->GetSleepTime(ev), somSelf->GetMouseRegion(ev) ) ;
  314.         if (eventRec.what == nullEvent)
  315.             somSelf->HandleNullEvent(ev, (ODEventData*) &eventRec, frame);    // Note Cast
  316.         else
  317.             somSelf->Dispatch(ev, (ODEventData*) &eventRec);
  318.     
  319.  
  320.     SOM_CATCH_ALL
  321.     SOM_ENDTRY
  322. }
  323.  
  324. SOM_Scope void  SOMLINK ODDispatcherSetMouseRegion(ODDispatcher *somSelf, Environment *ev,
  325.         ODRgnHandle area)
  326. {
  327.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  328.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherSetMouseRegion");
  329.  
  330.     if (area && _fPartMouseRegion)
  331.     {
  332.         CopyRgn(area, _fPartMouseRegion);
  333.     }
  334.  
  335. }
  336.  
  337. SOM_Scope ODRgnHandle  SOMLINK ODDispatcherGetMouseRegion(ODDispatcher *somSelf, Environment *ev)
  338. {
  339.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  340.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherGetMouseRegion");
  341.  
  342.     SOM_TRY
  343.  
  344.         if (somSelf->MouseRegionIsInvalid(ev))
  345.             somSelf->ComputeMouseRegion(ev);
  346.     
  347.     
  348.     /*
  349.     
  350.             CGrafPort desktopPort;                    // Used for showing cursor region 
  351.             long ticks;                                // Used for showing cursor region 
  352.             GrafPtr savedPort;                        // Used for showing cursor region 
  353.     
  354.             // Cursor region is in global coords. Need to create desktop port 
  355.             GetPort(&savedPort);
  356.             OpenCPort(&desktopPort);
  357.             CopyRgn(GetGrayRgn(), desktopPort.visRgn);
  358.             desktopPort.portRect = (*(desktopPort.visRgn))->rgnBBox;
  359.     
  360.             PenNormal();
  361.             PenMode(patXor);
  362.     
  363.             PaintRgn(_fPartMouseRegion);
  364.             Delay(30, &ticks);
  365.             PaintRgn(_fMouseRegion);
  366.     
  367.             CloseCPort(&desktopPort);
  368.             SetPort(savedPort);
  369.     
  370.     
  371.     */
  372.  
  373.     return _fMouseRegion;
  374.  
  375.     SOM_CATCH_ALL
  376.         
  377.         return kODNULL;
  378.         
  379.     SOM_ENDTRY
  380.     
  381.     return kODNULL;
  382. }
  383.  
  384. SOM_Scope void  SOMLINK ODDispatcherInvalidateFacetUnderMouse(ODDispatcher *somSelf, Environment *ev)
  385. {
  386.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  387.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherInvalidateFacetUnderMouse");
  388.  
  389.     SOM_TRY
  390.     
  391.         _fFacetUnderMouse = kODNULL;
  392.         somSelf->InvalidateMouseRegion(ev);
  393.         SetCursor(&ODQDGlobals.arrow);
  394.  
  395.     SOM_CATCH_ALL
  396.     SOM_ENDTRY
  397. }
  398.  
  399. SOM_Scope ODSLong  SOMLINK ODDispatcherGetSleepTime(ODDispatcher *somSelf, Environment *ev)
  400. {
  401.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  402.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherGetSleepTime");
  403.  
  404.     SOM_TRY
  405.     
  406.         // Don't sleep at all if another thread is ready to run:
  407.         if( ODAnyThreadsReady() )
  408.             return 0;
  409.     
  410.         return _fIdleList->GetMinIdleFrequency();
  411.  
  412.     SOM_CATCH_ALL
  413.         
  414.         return 0;
  415.     
  416.     SOM_ENDTRY
  417.     
  418.     return 0;
  419. }
  420.  
  421. static OSErr pascal HandleTSMEvents(const AppleEvent *theAppleEvent,
  422.                                         AppleEvent *reply,
  423.                                         long handlerRefcon)
  424. {
  425.     ODSession*        session = (ODSession*)handlerRefcon;
  426.     Environment*    ev = somGetGlobalEnvironment();
  427. //    DescType        eventID;
  428. //    DescType        actualType;
  429.     Size            maxSize = sizeof(DescType);
  430. //    Size            actualSize;
  431.     OSErr            result = noErr;
  432.     ODSemanticInterface* semtIntf = kODNULL; ODVolatile(semtIntf);
  433.     ODPart* keyPart = kODNULL; ODVolatile(keyPart);
  434.  
  435.     TRY
  436.         TempODFrame keyFrame
  437.             = session->GetArbitrator(ev)->AcquireFocusOwner(ev,
  438.                                                 session->Tokenize(ev,
  439.                                                                     kODKeyFocus));
  440.             // -- TÇ tempobj'd
  441.         if ((ODFrame*)keyFrame != kODNULL)
  442.         {
  443.             keyPart = keyFrame->AcquirePart(ev);
  444.             if (keyPart->HasExtension(ev, kODExtSemanticInterface))
  445.             {
  446.                 semtIntf = (ODSemanticInterface*)keyPart->AcquireExtension(ev,
  447.                                                         kODExtSemanticInterface);
  448.                 // WHAT WAS I GOING TO DO WITH THIS INFO? - NP 6/21/95
  449. //                result = AEGetAttributePtr(theAppleEvent, keyEventIDAttr,
  450. //                                                    typeType, &actualType,
  451. //                                                    (Ptr)&eventID, maxSize,
  452. //                                                    &actualSize);
  453. //                if (result || actualType != typeType || actualSize != maxSize)
  454. //                    THROW(errAEEventNotHandled);
  455.  
  456.                 // CREATE NEW ODAPPLEEVENTS FOR THE PARAMETERS
  457.                 ODAppleEvent*    odEvent = new ODAppleEvent;
  458.                 THROW_IF_NULL(odEvent);
  459.                 odEvent->InitODAppleEvent(ev);
  460.                 AEDescToODDesc((AEDesc*)theAppleEvent, odEvent);
  461.                 ODAppleEvent*    odReply = new ODAppleEvent;
  462.                 THROW_IF_NULL(odReply);
  463.                 odReply->InitODAppleEvent(ev);
  464.                 AEDescToODDesc((AEDesc*)reply, odReply);
  465.                 
  466.                 // PASS THE EVENT TO THE PART
  467.                 TRY
  468.                     semtIntf->CallEventHandler(ev, keyPart, odEvent, odReply);
  469.                 CATCH_ALL
  470.                     result = ErrorCode();
  471.                 ENDTRY
  472.                 
  473.                 // CLEAN UP. NOTE, WE MUST UPDATE THE REPLY DATAHANDLE SO THAT
  474.                 //    THE APPLE EVENTS MANAGER SEES THE CHANGE (IF ANY).
  475.                 delete odEvent;
  476.                 if (reply->descriptorType != typeNull
  477.                         && reply->dataHandle != kODNULL
  478.                         && !result)
  479.                 {
  480.                     ODByteArray data = odReply->GetRawData(ev);
  481.                     SetHandleSize(reply->dataHandle, data._length);
  482.                     THROW_IF_ERROR(MemError());
  483.                     ODBlockMove(data._buffer, *(reply->dataHandle),
  484.                                     data._length);
  485.                     DisposeByteArrayStruct(data);
  486.                 }
  487.                 delete odReply;
  488.             }
  489.             else
  490.                 result = errAEEventNotHandled;
  491.         }
  492.         else
  493.             result = errAEEventNotHandled;
  494.     CATCH_ALL
  495.         result = ErrorCode();
  496.     ENDTRY
  497.     
  498.     if ( semtIntf != kODNULL )
  499.         semtIntf->Release(ev);
  500.     if ( keyPart != kODNULL )
  501.         keyPart->Release(ev);
  502.  
  503.     return result;
  504. }
  505.  
  506. SOM_Scope void  SOMLINK ODDispatcherInitDispatcher(ODDispatcher *somSelf, Environment *ev,
  507.         ODSession* session)
  508. {
  509.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  510.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherInitDispatcher");
  511.     
  512.     const Boolean    kIsSysHandler = kODTrue;
  513.  
  514.     SOM_TRY
  515.  
  516.         /* Moved from somInit. SOM itself sets fields to zero
  517.         _fExit = kODFalse;
  518.         _fDispatchTable = kODNULL;
  519.         _fSession = kODNULL;
  520.         _fIdleList = kODNULL;
  521.     
  522.         _fMouseRegion = kODNULL;
  523.         _fPartMouseRegion = kODNULL;
  524.         _fFacetUnderMouse = kODNULL;
  525.         */
  526.         
  527.         somSelf->InitObject(ev);
  528.     
  529.         _fSession = session;
  530.     
  531.         _fDispatchTable = new DispatchTable;
  532.         THROW_IF_NULL(_fDispatchTable);
  533.         
  534.         _fIdleList = new IdleList;
  535.         THROW_IF_NULL(_fIdleList);
  536.         
  537.         _fMouseRegion = ODNewRgn();
  538.             
  539.         _fPartMouseRegion = ODNewRgn();
  540.     
  541.         ODStandardDispatchModule* stdModule = kODNULL;
  542.     
  543.         stdModule =    new ODStandardDispatchModule();
  544.         THROW_IF_NULL(stdModule);
  545.         stdModule->InitStandardDispatchModule(ev,session);
  546.         
  547.         somSelf->AddDispatchModule(ev,mouseDown,  stdModule);
  548.  
  549.         somSelf->AddDispatchModule(ev,mouseUp,    stdModule);
  550.         somSelf->AddDispatchModule(ev,keyDown,    stdModule);
  551.         somSelf->AddDispatchModule(ev,keyUp,      stdModule);
  552.         somSelf->AddDispatchModule(ev,autoKey,    stdModule);
  553.         somSelf->AddDispatchModule(ev,updateEvt,  stdModule);
  554.         somSelf->AddDispatchModule(ev,diskEvt,    stdModule);
  555.         somSelf->AddDispatchModule(ev,activateEvt,stdModule);
  556.         somSelf->AddDispatchModule(ev,osEvt,      stdModule);
  557.         somSelf->AddDispatchModule(ev,kHighLevelEvent, stdModule);
  558.         somSelf->AddDispatchModule(ev,kODEvtMenu, stdModule);
  559.         somSelf->AddDispatchModule(ev,kODEvtBGMouseDown, stdModule);
  560.         somSelf->AddDispatchModule(ev,kODEvtMouseDownBorder, stdModule);
  561.         somSelf->AddDispatchModule(ev,kODEvtMouseDownEmbedded, stdModule);
  562.         somSelf->AddDispatchModule(ev,kODEvtBGMouseDownEmbedded, stdModule);
  563.         somSelf->AddDispatchModule(ev,kODEvtMouseUpEmbedded, stdModule);
  564.     
  565.         // TSM support
  566.         AEEventHandlerUPP proc = NewAEEventHandlerProc(HandleTSMEvents);
  567.         THROW_IF_ERROR(AEInstallEventHandler(kTextServiceClass,
  568.                                                 kUpdateActiveInputArea,
  569.                                                 proc,
  570.                                                 (long)_fSession,
  571.                                                 !kIsSysHandler));
  572.         THROW_IF_ERROR(AEInstallEventHandler(kTextServiceClass, kPos2Offset,
  573.                                                 proc,
  574.                                                 (long)_fSession,
  575.                                                 !kIsSysHandler));
  576.         THROW_IF_ERROR(AEInstallEventHandler(kTextServiceClass, kOffset2Pos,
  577.                                                 proc,
  578.                                                 (long)_fSession,
  579.                                                 !kIsSysHandler));
  580.         THROW_IF_ERROR(AEInstallEventHandler(kTextServiceClass,
  581.                                                 kShowHideInputWindow,
  582.                                                 proc,
  583.                                                 (long)_fSession,
  584.                                                 !kIsSysHandler));
  585.     
  586.         // Background mouse-down support:
  587.         ODInstallBGMouseDownHandler(session);
  588.         
  589.         // Thread support:
  590.         ODInitThreads();
  591.  
  592.     SOM_CATCH_ALL
  593.     SOM_ENDTRY
  594. }
  595.  
  596. SOM_Scope void  SOMLINK ODDispatcherInvalidateMouseRegion(ODDispatcher *somSelf, Environment *ev)
  597. {
  598.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  599.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherInvalidateMouseRegion");
  600.  
  601.     SOM_TRY
  602.  
  603.         ASSERT(_fPartMouseRegion != kODNULL, kODErrDispatcherNotInitialized);
  604.         SetEmptyRgn(_fPartMouseRegion);
  605.  
  606.     SOM_CATCH_ALL
  607.     SOM_ENDTRY
  608. }
  609.  
  610. SOM_Scope ODFacet*  SOMLINK ODDispatcherGetFacetUnderMouse(ODDispatcher *somSelf, Environment *ev)
  611. {
  612.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  613.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherGetFacetUnderMouse");
  614.  
  615.     return _fFacetUnderMouse;
  616. }
  617.  
  618. SOM_Scope void  SOMLINK ODDispatcherSetFacetUnderMouse(ODDispatcher *somSelf, Environment *ev,
  619.         ODFacet* facet)
  620. {
  621.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  622.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherSetFacetUnderMouse");
  623.  
  624.  
  625.     _fFacetUnderMouse = facet;
  626.  
  627. }
  628.  
  629. SOM_Scope ODBoolean  SOMLINK ODDispatcherHandleNullEvent(ODDispatcher *somSelf, Environment *ev,
  630.         ODEventData* event,
  631.         ODFrame* skipFrame)
  632. {
  633.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  634.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherHandleNullEvent");
  635.  
  636.     ODBoolean handled = kODFalse;
  637.     
  638.     SOM_TRY
  639.     
  640.         // Give threads time to run:
  641.         ODYield();
  642.     
  643.         IdleListIterator iter(_fIdleList);
  644.         ODFrame* frame = kODNULL;
  645.         ODTicks now = TickCount();
  646.         
  647.         for (IdleInfo* idleInfo = iter.First(); iter.IsNotComplete(); idleInfo = iter.Next())
  648.         {
  649.             if ( (idleInfo->NeedsIdle( now )))
  650.             {
  651.                 frame = idleInfo->GetFrame(); 
  652.                 if ( (frame == kODNULL) || !ODObjectsAreEqual(ev, frame,skipFrame) ) 
  653.                 {
  654.                     TRY{
  655.                         idleInfo->GetPart()->HandleEvent(ev,event, frame, kODNULL, kODNULL);
  656.                     }CATCH_ALL{
  657.                         // ignore exception
  658.                     }ENDTRY
  659.                     idleInfo->SetLastIdle( now );
  660.                 }
  661.             }
  662.         }
  663.         handled = kODTrue;
  664.  
  665.     SOM_CATCH_ALL
  666.     SOM_ENDTRY
  667.     
  668.     return handled;
  669. }
  670.  
  671. SOM_Scope ODBoolean  SOMLINK ODDispatcherMouseRegionIsInvalid(ODDispatcher *somSelf, Environment *ev)
  672. {
  673.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  674.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherMouseRegionIsInvalid");
  675.  
  676.     ODBoolean isInvalid = kODTrue;
  677.  
  678.     if (Button())
  679.         return kODFalse;
  680.     
  681.     SOM_TRY
  682.  
  683.         ASSERT(_fPartMouseRegion != kODNULL, kODErrDispatcherNotInitialized);
  684.         isInvalid = EmptyRgn(_fPartMouseRegion);
  685.  
  686.     SOM_CATCH_ALL
  687.     SOM_ENDTRY
  688.     
  689.     return isInvalid;
  690. }
  691.  
  692. SOM_Scope void  SOMLINK ODDispatcherComputeMouseRegion(ODDispatcher *somSelf, Environment *ev)
  693. {
  694.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  695.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherComputeMouseRegion");
  696.  
  697.     SOM_TRY
  698.  
  699.         somSelf->CheckFacetUnderMouse(ev); // A Part may call SetMouseRegion
  700.         /*
  701.             if no frame is under the mouse, compute an appropriate big region
  702.             either way, add the current mouse location? 
  703.             And clip region to frame shape?
  704.         */
  705.     
  706.         // Add the current mouse location to whatever region is computed by the part
  707.         Point globalMouse;
  708.         GetMouse(&globalMouse);
  709.         LocalToGlobal(&globalMouse);
  710.         
  711.         SetRectRgn(_fMouseRegion, globalMouse.h, globalMouse.v, globalMouse.h + 1, globalMouse.v + 1);
  712.         UnionRgn(_fPartMouseRegion, _fMouseRegion, _fPartMouseRegion);
  713.  
  714.     SOM_CATCH_ALL
  715.     SOM_ENDTRY
  716. }
  717.  
  718. // <eeh> note: this code is a slightly modified version of IsThisKeyDown found
  719. // in ODDebug.cpp.  I'm using this instead because 1) I'm not sure it's available
  720. // when ODDebug isn't defined; and 2) because this calls GetKeys only once instead
  721. // of four times as would be necessary were IsThisKeyDown to be used.
  722.  
  723. inline Boolean OneDown( unsigned char keyMap[], ODUShort key )
  724.     { return ((keyMap[key >> 3] >> (key & 7)) & 1); }
  725.  
  726. ODBoolean IsThisKeyDown(ODUShort theKey);
  727. static ODSShort Modifiers()
  728. {
  729.     unsigned char theKeys[16];
  730.     GetKeys((UInt32*)&theKeys);
  731.  
  732.     ODSShort mods = 0;
  733.     // the index into the key map is the virtual keycode - 1....
  734.     if (OneDown(theKeys, 0x0038))
  735.         mods |= shiftKey;
  736.     if (OneDown(theKeys, 0x003A))
  737.         mods |= optionKey;
  738.     if (OneDown(theKeys, 0x003B))
  739.         mods |= controlKey;
  740.     if (OneDown(theKeys, 0x0037))
  741.         mods |= cmdKey;
  742.     return mods;
  743. }
  744.  
  745. SOM_Scope void  SOMLINK ODDispatcherCheckFacetUnderMouse(ODDispatcher *somSelf, Environment *ev)
  746. {
  747.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  748.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherCheckFacetUnderMouse");
  749.  
  750.     SOM_TRY
  751.  
  752.         Point globalPoint;
  753.         ODPoint windowPoint;
  754.     
  755.         GetMouse(&globalPoint);
  756.         LocalToGlobal(&globalPoint);
  757.     
  758.         if (!SetTSMCursor(globalPoint)) // NP: temporary. dispatcher really needs
  759.                                         //    to set a 1-pixel mouse region so that
  760.                                         //    SetTSMCursor can be called every time
  761.                                         //    the mouse moves.
  762.         {
  763.             ODWindow* odWindow = kODNULL;
  764.             ODFacet* foundFacet = kODNULL;
  765.         
  766.             ODWindowState* _fWindowState = _fSession->GetWindowState(ev); // temp
  767.             
  768.             TempODFrame mouseFocusFrame = kODNULL;
  769.             mouseFocusFrame = _fSession->GetArbitrator(ev)->AcquireFocusOwner(ev, _fSession->Tokenize(ev,kODMouseFocus));
  770.  
  771.             if (mouseFocusFrame)
  772.             {
  773.  
  774.                     if (_fFacetUnderMouse && ODObjectsAreEqual(ev, mouseFocusFrame, _fFacetUnderMouse->GetFrame(ev)))
  775.                     {
  776.                         odWindow = _fFacetUnderMouse->GetWindow(ev);
  777.                         odWindow->GetWindowPoint(ev, &globalPoint, &windowPoint);
  778.                         
  779.                         ODEventData event;
  780.                         SetEvent(event,kODEvtMouseWithin, globalPoint, Modifiers() );
  781.                         ODEventInfo info;
  782.                         SetEventInfo(info, windowPoint);
  783.                         WindowToLocal(ev, info.where, _fFacetUnderMouse);
  784.                     
  785.                         TempODPart part = mouseFocusFrame->AcquirePart(ev);
  786. #if ODDebug && ODLogEvents
  787.     LogEvent(&event, &info, mouseFocusFrame, _fFacetUnderMouse);
  788. #endif
  789.                         part->HandleEvent(ev, &event, mouseFocusFrame, _fFacetUnderMouse, &info);
  790.                     }
  791.                     return;
  792.             }
  793.  
  794.             odWindow = _fWindowState->FindODWindow(ev, &globalPoint);
  795.                 
  796.             if (odWindow)
  797.             {
  798.                 TempODWindow tempWindow = odWindow; // ensure it's released
  799.                 odWindow->GetWindowPoint(ev, &globalPoint, &windowPoint);
  800.                 TempODFrame activeFrame = _fSession->GetArbitrator(ev)->AcquireFocusOwner(ev, _fSession->Tokenize(ev,kODSelectionFocus));
  801.                 ODFacet* activeFacet = activeFrame ? GetActiveFacetWithBorderUnderPoint(ev, activeFrame, odWindow, windowPoint) : kODNULL;
  802.                 
  803.                 if (activeFacet)
  804.                     foundFacet = activeFacet->GetContainingFacet(ev);
  805.                 else
  806.                 {
  807.                     foundFacet = odWindow->GetFacetUnderPoint(ev, &windowPoint);
  808.                     if (foundFacet && (foundFacet->GetFrame(ev)->IsFrozen(ev) || foundFacet->IsSelected(ev)))
  809.                         foundFacet = foundFacet->GetContainingFacet(ev);
  810.                 }
  811.             }
  812.         
  813.             
  814.             if (ODObjectsAreEqual(ev, foundFacet, _fFacetUnderMouse))    
  815.             {
  816.                 if (foundFacet)
  817.                 {
  818.                     ODEventData event;
  819.                     SetEvent(event,kODEvtMouseWithin, globalPoint, Modifiers());
  820.                     ODEventInfo info;
  821.                     SetEventInfo(info, windowPoint);
  822.                     WindowToLocal(ev, info.where, _fFacetUnderMouse);
  823.                     
  824.                     ODFrame* frame = _fFacetUnderMouse->GetFrame(ev);
  825. #if ODDebug && ODLogEvents
  826.     LogEvent(&event, &info, frame, _fFacetUnderMouse);
  827. #endif
  828.                     TempODPart part = frame->AcquirePart(ev);
  829.                     part->HandleEvent(ev, &event, frame, _fFacetUnderMouse, &info);
  830.                 }
  831.             }
  832.             else
  833.             {        
  834.                 if (_fFacetUnderMouse)
  835.                 {
  836.                     ODEventData event;
  837.                     SetEvent(event,kODEvtMouseLeave, globalPoint, Modifiers());
  838.                     ODEventInfo info;
  839.                     SetEventInfo(info, windowPoint);
  840.                     WindowToLocal(ev, info.where, _fFacetUnderMouse);
  841.                     
  842.                     ODFrame* frame = _fFacetUnderMouse->GetFrame(ev);
  843. #if ODDebug && ODLogEvents
  844.     LogEvent(&event, &info, frame, _fFacetUnderMouse);
  845. #endif
  846.                     TempODPart part = frame->AcquirePart(ev);
  847.                     part->HandleEvent(ev, &event, frame, _fFacetUnderMouse, &info);
  848.                 }
  849.                 if (foundFacet)
  850.                 { 
  851.                     ODEventData event;
  852.                     SetEvent(event,kODEvtMouseEnter, globalPoint, Modifiers());
  853.                     ODEventInfo info;
  854.                     SetEventInfo(info, windowPoint);
  855.                     WindowToLocal(ev, info.where, foundFacet);
  856.                     
  857.                     ODFrame* frame = foundFacet->GetFrame(ev);
  858. #if ODDebug && ODLogEvents
  859.     LogEvent(&event, &info, frame, foundFacet);
  860. #endif
  861.                     TempODPart part = frame->AcquirePart(ev);
  862.                     part->HandleEvent(ev, &event,frame,foundFacet, &info);
  863.                 }
  864.                 _fFacetUnderMouse = foundFacet;
  865.             }
  866.         }
  867.  
  868.     SOM_CATCH_ALL
  869.     SOM_ENDTRY
  870. }
  871.  
  872. SOM_Scope void  SOMLINK ODDispatchersomUninit(ODDispatcher *somSelf)
  873. {
  874.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  875.     ODDispatcherMethodDebug("ODDispatcher","ODDispatchersomUninit");
  876.  
  877.      ODDeleteObject(_fDispatchTable);
  878.     ODDeleteObject(_fIdleList);
  879.     ODDisposeHandle((Handle)_fMouseRegion);
  880.     ODDisposeHandle((Handle)_fPartMouseRegion);
  881.    
  882.        parent_somUninit(somSelf);
  883. }
  884.  
  885. SOM_Scope ODSize  SOMLINK ODDispatcherPurge(ODDispatcher *somSelf, Environment *ev,
  886.         ODSize size)
  887. {
  888.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  889.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherPurge");
  890.  
  891.     ODUnused(size);
  892.     return 0;
  893. }
  894.  
  895. SOM_Scope void  SOMLINK ODDispatcherAddDispatchModule(ODDispatcher *somSelf, Environment *ev,
  896.         ODEventType eventType,
  897.         ODDispatchModule* dispatchModule)
  898. {
  899.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  900.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherAddDispatchModule");
  901.  
  902.     SOM_TRY
  903.  
  904.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  905.         
  906.         if (dispatchModule)
  907.         {
  908.             _fDispatchTable->AddDispatchModule(eventType,dispatchModule);
  909.         }
  910.         else
  911.             THROW(kODErrIllegalNullDispatchModuleInput);
  912.     
  913.  
  914.     SOM_CATCH_ALL
  915.     SOM_ENDTRY
  916. }
  917.  
  918. SOM_Scope ODDispatchModule*  SOMLINK ODDispatcherGetDispatchModule(ODDispatcher *somSelf, Environment *ev,
  919.         ODEventType eventType)
  920. {
  921.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  922.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherGetDispatchModule");
  923.     
  924.     ODDispatchModule* module = kODNULL;
  925.  
  926.     SOM_TRY
  927.  
  928.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  929.     
  930.         module = _fDispatchTable->GetDispatchModule( eventType );
  931.  
  932.     SOM_CATCH_ALL
  933.     SOM_ENDTRY
  934.     
  935.     return module;
  936. }
  937.  
  938. SOM_Scope void  SOMLINK ODDispatcherRemoveDispatchModule(ODDispatcher *somSelf, Environment *ev,
  939.         ODEventType eventType)
  940. {
  941.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  942.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherRemoveDispatchModule");
  943.  
  944.     SOM_TRY
  945.  
  946.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  947.         
  948.         _fDispatchTable->RemoveDispatchModule(eventType);
  949.  
  950.     SOM_CATCH_ALL
  951.     SOM_ENDTRY
  952. }
  953.  
  954. SOM_Scope void  SOMLINK ODDispatcherAddMonitor(ODDispatcher *somSelf, Environment *ev,
  955.         ODEventType eventType,
  956.         ODDispatchModule* dispatchModule)
  957. {
  958.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  959.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherAddMonitor");
  960.  
  961.     SOM_TRY
  962.  
  963.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  964.         
  965.         if (dispatchModule)
  966.             _fDispatchTable->AddMonitor(eventType,dispatchModule);        
  967.         else
  968.             THROW(kODErrIllegalNullDispatchModuleInput);
  969.  
  970.     SOM_CATCH_ALL
  971.     SOM_ENDTRY
  972. }
  973.  
  974. SOM_Scope void  SOMLINK ODDispatcherRemoveMonitor(ODDispatcher *somSelf, Environment *ev,
  975.         ODEventType eventType,
  976.         ODDispatchModule* dispatchModule)
  977. {
  978.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  979.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherRemoveMonitor");
  980.  
  981.     SOM_TRY
  982.  
  983.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  984.         
  985.         _fDispatchTable->RemoveMonitor(eventType, dispatchModule);
  986.  
  987.     SOM_CATCH_ALL
  988.     SOM_ENDTRY
  989. }
  990.  
  991.  
  992. static Boolean IntlTSMEvent(EventRecord *event) // NP: from TE 27.
  993. {
  994.     short oldFont;
  995.     ScriptCode keyboardScript;
  996.     
  997.     // make sure we have a port and it's not the Window Manager port
  998.     if (ODQDGlobals.thePort != nil && FrontWindow() != nil)
  999.     {
  1000.         oldFont = ODQDGlobals.thePort->txFont;
  1001.         keyboardScript = GetScriptManagerVariable(smKeyScript);
  1002.         if (FontToScript(oldFont) != keyboardScript)
  1003.             TextFont(GetScriptVariable(keyboardScript, smScriptAppFond));
  1004.     };
  1005.     return TSMEvent(event);
  1006. }
  1007.  
  1008. SOM_Scope ODBoolean  SOMLINK ODDispatcherDispatch(ODDispatcher *somSelf, Environment *ev,
  1009.         ODEventData* eventData)
  1010. {
  1011.     ODBoolean handled = kODFalse;
  1012.     
  1013.     SOM_TRY
  1014.  
  1015.         ODEventInfo eventInfo;    // Note: Need some utility functions
  1016.         eventInfo.embeddedFrame = kODNULL;
  1017.         eventInfo.embeddedFacet = kODNULL;
  1018.         ODPoint zero(0,0);
  1019.         eventInfo.where = zero;
  1020.         eventInfo.propagated = kODFalse;
  1021.     
  1022.         handled =somSelf->Redispatch(ev, eventData, &eventInfo);
  1023.     
  1024.     SOM_CATCH_ALL
  1025.     SOM_ENDTRY
  1026.     
  1027.     return handled;
  1028. }
  1029.  
  1030. SOM_Scope ODBoolean  SOMLINK ODDispatcherRedispatch(ODDispatcher *somSelf, Environment *ev,
  1031.         ODEventData* eventData,
  1032.         ODEventInfo* eventInfo)
  1033. {
  1034.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  1035.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherDispatch");
  1036.  
  1037.     ODBoolean handled = kODFalse;
  1038.     ODEventType eventType = eventData->what;     
  1039.  
  1040.     SOM_TRY
  1041.  
  1042.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  1043.         
  1044.         {
  1045.             OrderedCollection* monitors = kODNULL;
  1046.             ODDispatchModule* module = kODNULL;
  1047.             
  1048.             monitors = _fDispatchTable->GetMonitors(eventType);
  1049.             if (monitors)
  1050.             {
  1051.                 OrderedCollectionIterator iter(monitors);
  1052.                 
  1053.                 for (module = (ODDispatchModule*) iter.First(); 
  1054.                                 iter.IsNotComplete(); 
  1055.                                 module = (ODDispatchModule*) iter.Next())
  1056.                 {
  1057.                     module->Dispatch(ev, eventData, eventInfo);
  1058.                 }
  1059.             }
  1060.             
  1061.             if (!TSMEvent((EventRecord*)eventData))
  1062.             {
  1063.                 module = _fDispatchTable->GetDispatchModule(eventType);
  1064.                 if (module)
  1065.                     handled = module->Dispatch(ev, eventData, eventInfo);
  1066.             }
  1067.         }
  1068.         // Moved to the end so that dispatch modules can monitor or patch
  1069.         // null event handling
  1070.         if ((eventType == nullEvent) && !handled)
  1071.         {
  1072.             somSelf->HandleNullEvent(ev,eventData, kODNULL);
  1073.             handled = kODTrue;
  1074.         }
  1075.             
  1076.     SOM_CATCH_ALL
  1077.     SOM_ENDTRY
  1078.     
  1079.     return handled;
  1080. }
  1081.  
  1082. SOM_Scope void  SOMLINK ODDispatcherExit(ODDispatcher *somSelf, Environment *ev)
  1083. {
  1084.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  1085.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherExit");
  1086.  
  1087.     _fExit = kODTrue;
  1088. }
  1089.  
  1090. SOM_Scope ODBoolean  SOMLINK ODDispatcherShouldExit(ODDispatcher *somSelf, Environment *ev)
  1091. {
  1092.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  1093.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherShouldExit");
  1094.  
  1095.     return _fExit;
  1096. }
  1097.